package com.openway.game;

import com.openway.game.field.Coordinate;
import com.openway.game.field.PlayingField;
import com.openway.game.field.PlayingFieldImpl;
import com.openway.game.personage.MovingGameObject;
import com.openway.game.personage.impl.Drunkard;
import com.openway.game.personage.impl.Lamp;
import com.openway.game.personage.impl.Policeman;
import com.openway.game.personage.impl.Post;

import java.util.*;

/**
 * Class represent the game.
 * Only one game is supported, so this class is singleton (reduces the number of cross-references).
 * <p/>
 * Game objects can use playing field instance by {@link com.openway.game.Game#getInstance()#getPlayingField()}
 *
 * @author Created: 27.02.12 19:40
 * @version $Date$ $Revision$
 */
public class Game {
    private static final int NEW_DRUNKARD_PERIOD = 20;  //in how many steps there appears a new drunkard
    private static final Coordinate POST_COORDINATE = new Coordinate(7, 7);
    private static final Coordinate LAMP_COORDINATE = new Coordinate(3, 10);

    //SINGLETON
    private static Game instance = new Game();

    private Game() {
    }

    public static Game getInstance() {
        return instance;
    }
    //SINGLETON

    private int stepNumber;    //current step number
    private PlayingField playingField;
    private PoliceStation policeStation;
    private List<MovingGameObject> movingGameObjects;  //this field contains all moving objects that are in game (include sleeping and taken away drunkards)

    public void startNewGame() {
        stepNumber = 1;
        playingField = new PlayingFieldImpl();
        playingField.addObject(new Post(), POST_COORDINATE);
        playingField.addObject(new Lamp(), LAMP_COORDINATE);

        movingGameObjects = new ArrayList<MovingGameObject>();
        movingGameObjects.add(new Policeman());
        movingGameObjects.add(new Drunkard());

        policeStation = new PoliceStation();
    }

    /**
     * Make a game step
     */
    public void step() {
        if (stepNumber % NEW_DRUNKARD_PERIOD == 0) {
            movingGameObjects.add(new Drunkard());
        }

        for (MovingGameObject gameObject : movingGameObjects) {
            if (gameObject.canMove()) {
                gameObject.makeMove();

                if (gameObject instanceof Drunkard)
                    policeStation.addToTakenAwayIfNeeded((Drunkard) gameObject);
            }
        }

        stepNumber++;
    }


    public PlayingField getPlayingField() {
        return playingField;
    }

    public PoliceStation getPoliceStation() {
        return policeStation;
    }
}
